﻿///////////////////////////////////////////////////////////////////////////////
/// Copyright (c) by longshuang@msn.cn 2014.
/// All rights reserved.
///
/// @File	: Engine.Log.hpp
/// @Brief	: 日志记录
/// @Author	: Leo Zhao <longshuang@msn.cn>
/// @Date	: 2014-12-04
///
/// CHANGELOG
/// 	2014-12-04	基于文件的日志记录
///////////////////////////////////////////////////////////////////////////////
#ifndef		__ENGINE_LOG_HPP_INCLUDE__
#define		__ENGINE_LOG_HPP_INCLUDE__

#include	<ctime>
#include	<cstdio>
#include	<mutex>
#include	<string>

#define		GLogger(szName)	Engine::Log::Get(szName)

namespace Engine { namespace Log {

	/// @Brief	: 日志信息的不同级别
	enum ELevel {
		Error	= 0x1,
		Warn	= 0x2,
		Info	= 0x4,
		Debug	= 0x8,
		Normal	= Error | Info,
		All	 	= Error | Warn | Info | Debug
	};

	/// @Brief	: 基于文件的、线程安全的日志对象
	class Logger {
		friend class Manager;

	public:
		Logger(const char * pStrName);
		virtual ~Logger();

	#define LogError(pStrFmt, ...)	Error(__FILE__, __FUNCTION__, __LINE__, pStrFmt, ##__VA_ARGS__)
	#define LogDebug(pStrFmt, ...)	Debug(__FILE__, __FUNCTION__, __LINE__, pStrFmt, ##__VA_ARGS__)
	#define LogWarn(pStrFmt, ...)	Warn(__FILE__, __FUNCTION__, __LINE__, pStrFmt, ##__VA_ARGS__)
	#define LogInfo(pStrFmt, ...)	Info(__FILE__, __FUNCTION__, __LINE__, pStrFmt, ##__VA_ARGS__)

		/// @Brief	: 记录不同级别的日志信息
		/// @Param	: pStrFile	调用该函数的文件，宏__FILE__
		/// @Param	: pStrFunc	调用该函数的函数，宏__FUNCTION__
		/// @Param	: nLine		调用该函数的行号，宏__LINE__
		/// @Param	: pStrFmt	输出日志信息的格式
		/// @Param	: ...		格式化输出需要的参数列表
		/// @Return	: Nothing
		void	Error(const char * pStrFile, const char * pStrFunc, const int nLine, const char * pStrFmt, ...);
		void	Debug(const char * pStrFile, const char * pStrFunc, const int nLine, const char * pStrFmt, ...);
		void	Warn(const char * pStrFile, const char * pStrFunc, const int nLine, const char * pStrFmt, ...);
		void	Info(const char * pStrFile, const char * pStrFunc, const int nLine, const char * pStrFmt, ...);

	private:
		void	_Create();
		void	_Write(const char * pStrFile, const char * pStrFunc, const int nLine, ELevel emLvl, const char * pStrFmt, const char * pStrKey, va_list args);

	private:
		std::mutex		_iLock;
		size_t			_nWrited;
		FILE *			_pFile;
		int				_nDay;
		time_t			_nFlush;
		std::string		_szName;
		char			_pBuffer[1024];
	};

	/// @Brief	: 初始化日志文件的配置（存放位置、分割大小、记录级别等)
	/// @Param	: pStrPath	日志文件存放的目录
	/// @Param	: nMaxSize	日志文件分割大小
	/// @Param	: nLevelSet	控制需要记录的日志级别
	/// @Return	: Nothing
	extern void		Init(const char * pStrPath, const size_t nMaxSize, const int nLevelSet = ELevel::All, bool bEnableConsole = true);

	/// @Brief	: 获取一个日志文件对象的引用。自动管理。线程安全
	/// @Param	: pStrName	日志文件对象的名子，最长为64位的字串
	/// @Return	: 该日志对象的引用
	extern Logger &	Get(const char * pStrName);

} }

#endif//!	__ENGINE_LOG_HPP_INCLUDE__

